package ar.edu.utn.frgp.TPFinalBanco.action;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import ar.edu.utn.frgp.TPFinalBanco.model.Cliente;
import ar.edu.utn.frgp.TPFinalBanco.model.Cuenta;
import ar.edu.utn.frgp.TPFinalBanco.model.Movimiento;
import ar.edu.utn.frgp.TPFinalBanco.model.OrigenMovEnum;
import ar.edu.utn.frgp.TPFinalBanco.model.TipoMovimientoEnum;
import ar.edu.utn.frgp.TPFinalBanco.service.impl.GestionCuentaServiceImpl;
import ar.edu.utn.frgp.TPFinalBanco.service.impl.GestionMovimientosServiceImpl;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator;
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.ValidatorType;

public class ExtraerAction extends BaseAction implements Preparable {

	private static final long serialVersionUID = 1L;

	private Cliente cliente;
	private Date fecha;
	private String montoMov;
	private String cuentaElegida;

	public String execute() throws Exception {
		// obtenemos el cliente de la sesión
		cliente = (Cliente) ActionContext.getContext().getSession()
				.get("cliente");

		// Obtenemos la cuenta a la cual se va a extraer el dinero
		GestionCuentaServiceImpl cuentaService = (GestionCuentaServiceImpl) getContext()
				.getBean("gestionCuentasService");
		Cuenta cuenta = cuentaService
				.getCuenta(Integer.parseInt(cuentaElegida));
		
		BigDecimal monto = new BigDecimal(montoMov);

		if ((cuenta.getSaldo().add(cuenta.getDescubierto())).compareTo(monto) >= 0) {

			BigDecimal saldoActual = cuenta.getSaldo().subtract(monto);

			// Genero el movimiento y lo agrego en la BD
			Movimiento movimiento = new Movimiento(
					cuenta, new Date(),
					TipoMovimientoEnum.E, OrigenMovEnum.CJ, saldoActual,
					monto);
			GestionMovimientosServiceImpl movimientosService = (GestionMovimientosServiceImpl) getContext()
					.getBean("gestionMovimientosService");
			movimientosService.createMovimiento(movimiento);

			// Actualizo el saldo de la cuenta y lo guardo en la BD
			cuenta.setSaldo(saldoActual);
			cuentaService.updateCuenta(cuenta);

			// Actualizo la cuenta en la sesión
			List<Cuenta> cuentas = cliente.getCuentas();

			for (Cuenta cuentaCliente : cuentas) {
				if (cuentaCliente.getNroCuenta().equals(cuenta.getNroCuenta())) {
					cuentaCliente.setSaldo(saldoActual);
				}
			}

			cliente.setCuentas(cuentas);
			ActionContext.getContext().getSession().put("cliente", cliente);

			return SUCCESS;
		} else {
			addActionError("No posee dinero suficiente para extraer ese monto, por favor ingrese un monto menor.");
			return ERROR;
		}

	}

	public Cliente getCliente() {
		return cliente;
	}

	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}

	public Date getFecha() {
		return fecha;
	}

	public void setFecha(Date fecha) {
		this.fecha = fecha;
	}

	public String getMontoMov() {
		return montoMov;
	}

	@RegexFieldValidator(message = "El monto debe ser del tipo nnn,nn", shortCircuit = true, expression = "^[0-9]+(,[0-9]{1,2})?$")
	@RequiredStringValidator(message = "Campo Obligatorio: Debe ingresar un monto", type = ValidatorType.FIELD, shortCircuit = true, fieldName = "montoMov", trim = true)
	public void setMontoMov(String montoMov) {
		this.montoMov = montoMov;
	}

	public String getCuentaElegida() {
		return cuentaElegida;
	}

	public void setCuentaElegida(String cuentaElegida) {
		this.cuentaElegida = cuentaElegida;
	}

	public void prepare() throws Exception {
		cliente = (Cliente) ActionContext.getContext().getSession()
				.get("cliente");
		
	}

}
